using Dapper;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement.Billing;
using System.Data;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement.Billing
{
    /// <summary>
    /// 创建开票通知单处理器
    /// </summary>
    public class CreateBillingNoticeHandler : IRequestHandler<CreateBillingNoticeCommand, APIResult<int>>
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbConnectionFactory">数据库连接工厂</param>
        public CreateBillingNoticeHandler(IDbConnectionFactory dbConnectionFactory)
        {
            _dbConnectionFactory = dbConnectionFactory;
        }

        /// <summary>
        /// 处理创建开票通知单请求
        /// </summary>
        /// <param name="request">创建命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public async Task<APIResult<int>> Handle(CreateBillingNoticeCommand request, CancellationToken cancellationToken)
        {
            IDbConnection connection = null;
            IDbTransaction transaction = null;

            try
            {
                // 创建数据库连接
                connection = _dbConnectionFactory.CreateConnection();

                // 开始事务
                transaction = connection.BeginTransaction();

                // 1. 自动生成单据编号
                var billNumber = await GenerateBillNumberAsync(connection, transaction);

                // 2. 插入开票通知单主表
                var billingNoticeId = await InsertBillingNoticeAsync(connection, transaction, request, billNumber);

                // 3. 插入开票物料明细表
                if (request.Items != null && request.Items.Count > 0)
                {
                    await InsertBillingMaterialsAsync(connection, transaction, request.Items, billingNoticeId);
                }

                // 4. 提交事务
                transaction.Commit();

                return new APIResult<int>
                {
                    Code = APIEnums.Success,
                    Msg = "开票通知单创建成功",
                    Data = billingNoticeId
                };
            }
            catch (Exception ex)
            {
                // 回滚事务
                if (transaction != null)
                {
                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception rollbackEx)
                    {
                        // 记录回滚异常
                        Console.WriteLine($"事务回滚失败: {rollbackEx.Message}");
                    }
                }

                return new APIResult<int>
                {
                    Code = APIEnums.Fail,
                    Msg = "创建开票通知单失败：" + ex.Message,
                    Data = 0
                };
            }
            finally
            {
                // 确保连接被正确关闭
                if (connection != null && connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }
            }
        }

        /// <summary>
        /// 自动生成单据编号
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <returns>单据编号</returns>
        private async Task<string> GenerateBillNumberAsync(IDbConnection connection, IDbTransaction transaction)
        {
            try
            {
                // 查询当前最大单据编号
                var sql = @"
                    SELECT BillNumber 
                    FROM BillingAccounting 
                    WHERE BillNumber LIKE 'KP%' 
                    AND IsDeleted = 0
                    ORDER BY BillNumber DESC 
                    LIMIT 1";

                var lastBillNumber = await connection.QueryFirstOrDefaultAsync<string>(sql, null, transaction);

                if (string.IsNullOrEmpty(lastBillNumber))
                {
                    // 如果没有记录，从KP000001开始
                    return "KP000001";
                }

                // 提取数字部分并加1
                if (lastBillNumber.Length >= 3 && int.TryParse(lastBillNumber.Substring(2), out int currentNumber))
                {
                    var nextNumber = currentNumber + 1;
                    return $"KP{nextNumber:D6}";
                }

                // 如果解析失败，返回默认值
                return "KP000001";
            }
            catch
            {
                return "KP000001";
            }
        }

        /// <summary>
        /// 插入开票通知单主表
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <param name="request">创建请求</param>
        /// <param name="billNumber">单据编号</param>
        /// <returns>主表ID</returns>
        private async Task<int> InsertBillingNoticeAsync(
            IDbConnection connection,
            IDbTransaction transaction,
            CreateBillingNoticeCommand request,
            string billNumber)
        {
            var sql = @"
                INSERT INTO BillingAccounting (
                    BillNumber, BusinessType, CustomerName, BankName, ProductCode, 
                    DeliveryEmail, BillDate, Operator, InvoiceType, TaxId, 
                    AddressPhone, Remarks, CreateTime, CreateUser, IsDeleted, Status, BusinessStatus, BillStatus
                ) VALUES (
                    @BillNumber, @BusinessType, @CustomerName, @BankName, @AccountNumber,
                    @DeliveryEmail, @BillDate, @Operator, @InvoiceType, @TaxNumber,
                    @AddressPhone, @Remarks, @CreateTime, @CreateUser, @IsDeleted, @Status, @BusinessStatus, @BillStatus
                );
                SELECT LAST_INSERT_ID();";

            // 根据状态值映射为中文状态
            string billStatusText = request.Status switch
            {
                0 => "开立",
                1 => "审核",
                2 => "退回",
                _ => "开立" // 默认状态
            };

            var parameters = new
            {
                BillNumber = billNumber,
                BusinessType = request.BusinessType,
                CustomerName = request.CustomerName,
                BankName = request.BankName,
                AccountNumber = request.AccountNumber,
                DeliveryEmail = request.DeliveryEmail,
                BillDate = request.BillDate ?? DateTime.Now,
                Operator = request.Operator ?? "System", // 使用前端传来的操作员信息
                InvoiceType = request.InvoiceType,
                TaxNumber = request.TaxNumber,
                AddressPhone = request.AddressPhone,
                Remarks = request.Remarks,
                CreateTime = DateTime.Now,
                CreateUser = "admin", // 创建人默认为admin
                IsDeleted = false,
                Status = request.Status, // 单据状态，默认0-开立
                BusinessStatus = request.BusinessStatus, // 业务状态，默认"正常"
                BillStatus = billStatusText // 单据状态文本
            };

            return await connection.QuerySingleAsync<int>(sql, parameters, transaction);
        }

        /// <summary>
        /// 插入开票物料明细表
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <param name="items">物料明细列表</param>
        /// <param name="billingNoticeId">开票通知单ID</param>
        private async Task InsertBillingMaterialsAsync(
            IDbConnection connection,
            IDbTransaction transaction,
            List<CreateBillingMaterialDto> items,
            int billingNoticeId)
        {
            var sql = @"
                INSERT INTO BillingMaterials (
                    OrderNumber, MaterialCode, MaterialName, Unit, Quantity, 
                    UnitPrice, Amount, InvoiceName, Remarks, 
                    BillingAccountingId, CreateTime, CreateUser, IsDeleted
                ) VALUES (
                    @OrderNumber, @MaterialCode, @MaterialName, @Unit, @Quantity,
                    @UnitPrice, @Amount, @InvoiceName, @Remarks,
                    @BillingAccountingId, @CreateTime, @CreateUser, @IsDeleted
                )";

            foreach (var item in items)
            {
                var parameters = new
                {
                    OrderNumber = item.OrderNumber,
                    MaterialCode = item.MaterialCode,
                    MaterialName = item.MaterialName,
                    Unit = item.Unit,
                    Quantity = item.Quantity,
                    UnitPrice = item.UnitPrice,
                    Amount = item.Amount,
                    InvoiceName = item.InvoiceName,
                    Remarks = item.Remarks,
                    BillingAccountingId = billingNoticeId,
                    CreateTime = DateTime.Now,
                    CreateUser = "admin", // 创建人默认为admin
                    IsDeleted = false
                };

                await connection.ExecuteAsync(sql, parameters, transaction);
            }
        }
    }
}